#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""
@File    :   rf.py
@Time    :   2024-07-09 12:58
@Author  :   坐公交也用券
@Version :   1.0
@Contact :   faith01238@hotmail.com
@Homepage : https://liumou.site
@Desc    :   用于检测BT下载完成的文件进行删除
"""
import logging
import os
import pathlib
import sqlite3
import subprocess
import sys
from argparse import ArgumentParser
from sys import exit
from time import sleep

# 定义配置文件路径,使用主目录+文件名拼
config_dir = os.path.join(pathlib.Path.home(), ".config", "com.liumou.rf")
# 判断目录是否存在，不存在则创建
if not os.path.exists(config_dir):
	os.makedirs(config_dir)
config_ = os.path.join(config_dir, "config.db")

# 创建一个自定义的日志记录器
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# 创建一个自定义的日志处理器，设置其输出格式
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(filename)s:%(lineno)d | %(funcName)s | %(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)

service = f"""[Unit]
Description=这是一个自动检测删除某个路径下指定后缀的服务
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/com.liumou.rf -db {config_}
StandardOutput=journal
KillMode=control-group
Restart=on-failure
RestartPreventExitStatus=255
StandardError=inherit
SyslogIdentifier=com.liumou.rf

[Install]
WantedBy=multi-user.target
Alias=com.liumou.rf.service
"""


class Db:
	def __init__(self, file: str, debug=False):
		"""
		操作数据库
		:param file: 数据库文件
		:param debug: 是否开启调试模式
		"""
		self.debug = debug
		self.file = file
		self.db = sqlite3.connect(self.file)
		self.cursor = self.db.cursor()
		self.create()

	def close(self):
		"""
		关闭数据库
		:return:
		"""
		self.db.close()

	def create(self):
		"""
		创建数据表
		:return:
		"""
		# 先判断数据表是否存在
		sql = '''SELECT name FROM sqlite_master WHERE type='table' AND name='bt';'''
		if self.debug:
			logger.debug(sql)
		# 开始查询
		self.cursor.execute(sql)
		results = self.cursor.fetchall()
		if results:
			if self.debug:
				logger.debug('数据表已存在, 不需要创建')
			return
		try:
			self.cursor.execute('''CREATE TABLE IF NOT EXISTS bt(id INTEGER PRIMARY KEY,p TEXT, format TEXT)''')
			self.db.commit()
			logger.info('创建数据表成功')
		except Exception as e:
			logger.error(e)

	def add(self, p, format_):
		"""
		添加数据
		:param p:
		:param format_:
		:return:
		"""
		if self.exists(p, format_):
			return
		try:
			self.cursor.execute('''INSERT INTO bt(p, format) VALUES (?, ?);''', (p, format_))
			self.db.commit()
		except Exception as e:
			logger.error(e)
		finally:
			# self.db.close()
			logger.info('添加数据成功')

	def delete(self, p, format_):
		"""
		删除数据
		:param p:
		:param format_:
		:return:
		"""
		if not self.exists(p, format_):
			return
		sql = '''DELETE FROM bt WHERE ''' + f"id='{p}' and format='{format_}';"
		if self.debug:
			logger.debug(sql)
		try:
			self.cursor.execute(sql)
			self.db.commit()
		except Exception as e:
			logger.error(e)
			return
		logger.info(f'删除数据成功: {p} {format_}')

	def exists(self, p, format_):
		"""
		查询数据是否存在
		:param p: 需要查询的路径
		:param format_: 需要查询的格式
		:return:
		"""
		sql = '''SELECT * FROM bt WHERE ''' + f"p='{p}' and format='{format_}';"
		if self.debug:
			logger.debug(sql)
		self.cursor.execute(sql)
		results = self.cursor.fetchall()
		if results:
			logger.info(f'数据已存在: {p} {format_}')
			return True
		else:
			logger.info(f'数据不存在: {p} {format_}')
			return False


class BtManger:
	def __init__(self, debug):
		"""

		:param debug:
		"""
		self.debug = debug
		self.config = config_
		self.db = Db(config_, debug)

	def close(self):
		"""
		关闭数据库
		:return:
		"""
		self.db.close()

	def delete(self):
		"""
		删除
		:return:
		"""
		self.get()
		logger.info("正在进行删除...")
		c = True
		while c:
			path_ = input("请输入需要删除的路径\n")
			format_ = input("请输入需要删除的格式\n")
			self.db.delete(path_, format_)
			# 是否继续
			y = input("是否继续删除(y/n): \n")
			if y.lower().strip() != "y".lower():
				c = False

	def add(self):
		"""
		添加
		:return:
		"""
		logger.info("正在进行添加...")
		c = True
		while c:
			path_ = input("请输入需要检测的路径\n")
			format_ = input("请输入需要添加的格式\n")
			path_ = os.path.abspath(path_)
			self.db.add(path_, format_)
			# 是否继续
			y = input("是否继续添加(y/n): \n")
			if y.lower().strip() != "y".lower():
				c = False

	def update(self):
		"""
		更新
		:return:
		"""
		logger.info("正在进行更新...")
		self.get()
		self.delete()
		self.add()

	def install(self):
		"""
		安装
		:return:
		"""
		logger.info("正在进行安装/更新...")
		self.add()
		install_service()

	def get(self):
		"""
		获取
		:return:
		"""
		self.db.cursor.execute('SELECT * FROM bt')
		data_ = self.db.cursor.fetchall()
		if data_:
			for i_ in data_:
				print(f"[{i_[0]}] {i_[1]} {i_[2]}")
		else:
			logger.info("暂无数据")


def install_service():
	"""

	:return:
	"""
	# 安装服务
	# 首先删除已存在的服务文件
	os.system("rm -f /etc/systemd/system/com.liumou.rf.service")
	# 将服务文件写入
	try:
		with open('/etc/systemd/system/com.liumou.rf.service', 'w') as f:
			f.write(service)
	except Exception as e:
		logger.error(e)
		exit(1)
	os.system("systemctl daemon-reload")
	os.system("systemctl enable com.liumou.rf.service")
	os.system("systemctl restart com.liumou.rf.service")
	logger.info("安装/更新成功")
	exit(0)
	rf_url = 'https://gitee.com/liumou_site/pvet/raw/master/model/bt/rf.py'
	rf_bin = os.path.join("/usr/bin/com.liumou.rf")
	os.system(f"rm -f {rf_bin}")
	res = subprocess.getstatusoutput(f'wget -O {rf_bin} {rf_url}')
	if res[0] == 0:
		os.system(f"chmod 0755 {rf_bin}")
		logger.info("安装/更新成功")
		exit(0)
	else:
		logger.error("安装/更新失败")
		print(res[1])
		exit(2)


class BtDelete:
	def __init__(self, debug):
		"""
		"""
		self.debug = debug
		self.f = None
		self.p = None
		self.file_list = []
		self.data = {}

	def get_db(self):
		"""
		获取数据库
		:return:
		"""
		db = Db(config_, True)
		self.data = db.cursor.execute('SELECT * FROM bt').fetchall()

	def get_file(self):
		"""
		获取文件列表
		:param self:
		:return:
		"""
		self.file_list = []
		for root, dirs, files in os.walk(self.p):
			for name in files:
				file = os.path.join(root, name)
				print(f"获取文件: {file}")
				self.file_list.append(file)

	def check_format(self):
		"""
		检测文件格式
		:return:
		"""
		for i in self.file_list:
			# 获取文件格式
			file_format = str(i.split('.')[-1]).strip().lower()
			# print(f"文件格式: {file_format}")
			# print(self.f)
			# 判断是否在格式列表中
			if file_format.lower() == self.f.lower():
				print(f"删除文件: {i}")
				try:
					os.remove(i)
				except Exception as e:
					print(e)
					continue
				print(f"删除成功: {i}")

	def start(self):
		"""
		开始检测
		:return:
		"""
		# 使用无限循环
		while True:
			self.get_db()
			for i in self.data:
				self.p = i[1]
				self.f = i[2]
				self.get_file()
				print(f"检测文件数量: {len(self.file_list)}")
				self.check_format()
				sleep(10)


if __name__ == '__main__':
	arg = ArgumentParser(description='当前脚本版本: 1.0', prog="查找指定后缀文件并删除")
	arg.add_argument('-db', '--db', type=str, default=config_, help=f'配置文件路径,默认: {config_}')
	arg.add_argument('-v', '--version', action='version', version='%(prog)s 1.0')
	arg.add_argument('-install', action='store_true', help='安装/更新服务')
	arg.add_argument('-add', action='store_true', help='添加数据')
	arg.add_argument('-delete', action='store_true', help='删除数据')
	arg.add_argument('-update', action='store_true', help='更新数据')
	arg.add_argument('-get', action='store_true', help='查询当前数据')
	arg.add_argument('-debug', action='store_true', help='调试模式')
	args = arg.parse_args()
	bm = BtManger(debug=args.debug)
	if args.install:
		bm.install()
		bm.close()
		exit(0)
	if args.add:
		bm.add()
		bm.close()
		exit(0)
	if args.delete:
		bm.delete()
		bm.close()
		exit(0)
	if args.update:
		bm.update()
		bm.close()
		exit(0)
	if args.get:
		bm.get()
		bm.close()
		exit(0)
	config_ = args.db
	print(f"数据库文件: {config_}")
	bt = BtDelete(debug=args.debug)
	bt.start()
